#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <ctime>
#include <cstdlib>
#include <iomanip>

#include "../../db_redis.hpp"
#include "../../dbManager.hpp"
#include "../../Util.hpp"
// 根据用户名和密码生成会话令牌
// 此处只为演示 实际的会话令牌需要更复杂安全的算法如JWT
std::string generateSessionToken(const std::string &username, const std::string &password)
{
    // 生成随机令牌
    srand(time(0));
    std::string token = username + std::to_string(rand() % 1000) + password;
    token = Util::UrlEncode(token);
    return token;
}

// /cgi/login_get?username=lhr&password=123
int main()
{
    std::string reqParam;
    Util::GetReqParam(reqParam);

    std::string str1;
    std::string str2;
    Util::CutString(reqParam, str1, str2, "&");

    std::string usrName;
    std::string usr_name;
    Util::CutString(str1, usrName, usr_name, "=");
    usr_name = Util::UrlDecode(usr_name);

    std::string usrPasswd;
    std::string usr_passwd;
    Util::CutString(str2, usrPasswd, usr_passwd, "=");

    // debug：输出到管道 父进程通过管道读取
    // std::cout << usrName << " : " << usr_name << std::endl;
    // std::cout << usrPasswd << " : " << usr_passwd << std::endl;
    // debug：输出到显示器
    // std::cerr << usrName << " : " << usr_name << std::endl;
    // std::cerr << usrPasswd << " : " << usr_passwd << std::endl;

    // 获取数据库单例
    DBManager &db = DBManager::GetInstance();
    int ret = db.CheckUser(usr_name, usr_passwd);

    Json::Value result;
    std::string token;

    if (ret == 0) // 登录成功
    {
        token = generateSessionToken(usr_name, usr_passwd); // 生成会话令牌
        result["success"] = true;
        result["message"] = "登录成功";
        db.InsertToken(usr_name, token);
        db.UpdateLastLoginTime(usr_name);

        // 写入Redis（1小时过期）
        RedisManager &redis = RedisManager::GetInstance();
        redis.InsertToken(token, usr_name, 3600);
    }
    else if (ret == NO_USR) // 用户不存在
    {
        result["success"] = false;
        result["message"] = "用户不存在";
    }
    else if (ret == PASSWD_ERR) // 密码错误
    {
        result["success"] = false;
        result["message"] = "密码错误";
    }
    else // 服务器错误
    {
        result["success"] = false;
        result["message"] = "服务器内部错误";
    }

    std::string http_resBody = result.toStyledString();
    // 向管道输出cgi请求的http响应
    std::string http_res;
    http_res += "HTTP/1.0 200 OK\r\n";
    http_res += "Content-Type: application/json\r\n";
    http_res += "Content-Length: ";
    http_res += std::to_string(http_resBody.length());
    http_res += "\r\n";
    // 设置cookie过期时间为1小时
    std::string SetCookie = "Set-Cookie: session_token=" + token + "; HttpOnly; Path=/; Max-Age=3600\r\n";
    http_res += result["success"] == true ? SetCookie : "";
    http_res += "\r\n";
    http_res += http_resBody;

    std::cout << http_res;
    return 0;
}
